package com.ssm.basis.service.util;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.*;

/**
 * 安全认证工具类
 */
public abstract class SecurityUtil {
    public static Map<String, Object> getAuthenticationResult() {
        return getAuthenticationResult(getAuthentication());
    }

    public static Map<String, Object> getAuthenticationResult(Authentication authentication) {
        Map<String, Object> authenticationResult = new LinkedHashMap<>();

        authenticationResult.put("name", authentication.getName());
        Set<String> authorities = new HashSet<>(authentication.getAuthorities().size());
        authentication.getAuthorities().forEach(grantedAuthority -> authorities.add(grantedAuthority.getAuthority()));
        authenticationResult.put("authorities", authorities);
        authenticationResult.put("principal", authentication.getPrincipal());
        return authenticationResult;
    }

    public static void switchCurrentUser(UserDetails details) {
        Authentication token = new UsernamePasswordAuthenticationToken(details, details.getPassword(), details.getAuthorities());
        getSecurityContext().setAuthentication(token);
    }

    public boolean isLoggedIn() throws Exception {
        Authentication authentication = getAuthentication();
        return Objects.nonNull(authentication) && authentication.getPrincipal() instanceof User;
    }

    public static String getUserName() {
        return Objects.requireNonNull(getUser()).getUsername();
    }

    public static User getUser() {
        Authentication authentication = getAuthentication();
        if (authentication.getPrincipal() instanceof User) {
            return (User) authentication.getPrincipal();
        }
        return null;
    }

    public static Authentication getAuthentication() {
        return getSecurityContext().getAuthentication();
    }

    @PreAuthorize("isAuthenticated()")
    public static SecurityContext getSecurityContext() {
        return SecurityContextHolder.getContext();
    }
}